<template>
  <div class="ProDrawRange-box" :class="{ disabled: disableAction }">
    <el-row :gutter="20">
      <el-col :lg="12">
        <el-divider content-position="left">抽取内容</el-divider>
        <el-form inline size="small">
          <el-form-item style="margin-bottom: 0" key="currDeptId1" v-if="isJq">
            <el-select v-model="currDeptId1" placeholder="请选择集群" filterable :loading="dept1Loading" :disabled="disableAction || isSuppDraw" @change="changeDeptId1" style="width: 130px">
              <el-option v-for="item in dept1List" :key="item.fid" :label="item.deptName" :value="item.fid" />
            </el-select>
          </el-form-item>
          <el-form-item style="margin-bottom: 0">
            <el-select v-model="currBsNode.bsNodeId" placeholder="检查类型" filterable :loading="bsNodeLoading" :disabled="disableAction || isSuppDraw" @change="changeBsNode" style="width: 130px">
              <el-option v-for="item in bsNodeList" :key="item.bsNodeId" :label="item.businessType" :value="item.bsNodeId" />
            </el-select>
          </el-form-item>
          <el-form-item style="margin-bottom: 0">
            <div class="el-input-group el-input-group--prepend">
              <div class="el-input-group__prepend">抽取项目数</div>
              <el-input-number v-model="projectNum" :min="0" :max="1e3" :precision="0" controls-position="right" style="width: 90px" />
            </div>
          </el-form-item>
        </el-form>
      </el-col>
      <el-col :lg="12">
        <el-divider content-position="left">
          抽取前置条件
          <el-tooltip placement="top">
            <div slot="content">
              若需要指定集群（或事业部/城市公司）的抽取数量，请在以下对应的输入框输入数量。<br>
              例如：需要指定事业部的抽取数量，请在事业部输入框输入数量
            </div>
            <i class="el-icon-question" style="color: #909399" />
          </el-tooltip>
        </el-divider>
        <el-form inline size="small">
          <el-form-item style="margin-bottom: 0">
            <div class="el-input-group el-input-group--prepend">
              <div class="el-input-group__prepend">集群</div>
              <el-input-number v-model="colNum" placeholder="抽取数量" :min="0" :max="1e3" :precision="0" :controls="false" style="width: 90px" />
            </div>
          </el-form-item>
          <el-form-item style="margin-bottom: 0">
            <div class="el-input-group el-input-group--prepend">
              <div class="el-input-group__prepend">事业部</div>
              <el-input-number v-model="bussNum" placeholder="抽取数量" :min="0" :max="1e3" :precision="0" :controls="false" style="width: 90px" />
            </div>
          </el-form-item>
          <el-form-item style="margin-bottom: 0">
            <div class="el-input-group el-input-group--prepend">
              <div class="el-input-group__prepend">城市公司</div>
              <el-input-number v-model="cityNum" placeholder="抽取数量" :min="0" :max="1e3" :precision="0" :controls="false" style="width: 90px" />
            </div>
          </el-form-item>
        </el-form>
      </el-col>
    </el-row>

    <el-divider content-position="left">项目抽取范围</el-divider>
    <div style="margin-bottom: 10px" :class="{ disabled: disableAction }">
      <el-button size="mini" :disabled="!filteredList.length" @click="selectAll">全选</el-button>
      <el-button size="mini" :disabled="!filteredList.length" @click="selectInvert">反选</el-button>

      <el-dropdown @command="onReloadType" :disabled="listLoading">
        <el-button size="mini" icon="el-icon-refresh" :loading="listLoading" style="margin-left: 10px">
          {{ isLastTime ? '加载最近一次' : '条件加载' }}
          <i class="el-icon-arrow-down el-icon--right" />
        </el-button>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item command="condition" style="font-size: 12px">条件加载</el-dropdown-item>
          <el-dropdown-item command="lastTime" style="font-size: 12px">加载最近一次</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>

      <el-button size="mini" type="warning" :disabled="!selected.length" icon="el-icon-delete" style="margin-left: 10px" @click="removeSelected" v-if="showBtns.removePrj">移除范围项目</el-button>
      <el-button size="mini" type="primary" icon="el-icon-plus" :disabled="listLoading" @click="openSelectProList" v-if="showBtns.addPrj">新增范围项目</el-button>
      <el-input size="mini" v-model.trim="toggleInput" placeholder="输入内容" clearable @clear="handleQuery" @keyup.enter.native="handleQuery" style="width: 300px; margin-left: 10px">
        <el-select v-model="toggleSelect" slot="prepend" placeholder="选择范围" style="width: 100px">
          <el-option label="项目名称" value="displayName" />
          <el-option label="集群" value="deptName1" />
          <el-option label="事业部" value="deptName2" />
          <el-option label="城市公司" value="deptName3" />
        </el-select>
        <el-button slot="append" type="primary" icon="el-icon-search" @click="handleQuery" />
      </el-input>
    </div>
    <div class="table-wrap">
      <!--
      <div class="first-load-btns" v-if="firstTimeComing">
        <div class="btns">
          <el-button class="btn btn1" type="primary" size="mini" @click="onReloadType('condition')">条件加载</el-button>
          <el-button class="btn btn2" type="success" size="mini" @click="onReloadType('lastTime')">加载最近一次</el-button>
        </div>
        <div class="desc">
          <div style="border-bottom: 1px solid #dcdfe6">根据{{ currBsNode.businessType }}的进入条件与退出条件加载项目抽取范围</div>
          <div>加载最近一次{{ currBsNode.businessType }}抽取范围数据</div>
        </div>
      </div>
      -->
      <poor-process ref="poorProcessRef" @onReloadType="onReloadType" />
      <el-table ref="table" :data="filteredList" size="small" height="calc(88vh - 380px)" style="min-height: 300px" @row-click="rowClick" @selection-change="onSelect">
        <span slot="empty">{{ firstTimeComing || listLoading ? '' : '暂无数据' }}</span>
        <el-table-column type="selection" width="50" align="center" :selectable="row => row.status >= 0" />
        <el-table-column label="集群" prop="deptName1" show-overflow-tooltip min-width="100" />
        <el-table-column label="事业部" prop="deptName2" show-overflow-tooltip min-width="100" />
        <el-table-column label="城市公司" prop="deptName3" show-overflow-tooltip min-width="100" />
        <el-table-column label="项目" prop="displayName" show-overflow-tooltip min-width="150" />
        <el-table-column label="状态" align="center" min-width="80">
          <dict-tag slot-scope="{ row }" :options="proRangeStatusList" :value="row.status" />
        </el-table-column>
        <el-table-column label="操作" align="center" width="120">
          <template slot-scope="{ row }">
            <el-button size="mini" type="text" icon="el-icon-delete" :loading="row.removeLoading" @click.stop="handleDelete(row)" v-if="showBtns.removePrjForever && row.status === 1">永久删除</el-button>
            <el-button size="mini" type="text" icon="el-icon-delete" @click.stop="removeManuallyAdded(row)" v-else-if="showBtns.addPrj && row.status === 2">移除范围项目</el-button>
            <el-button size="mini" type="text" icon="el-icon-refresh-left" @click.stop="statusCancelToNormal(row)" v-else-if="showBtns.removePrj && row.status === -1">恢复</el-button>
            <el-button size="mini" type="text" icon="el-icon-refresh-left" :loading="row.removeLoading" @click.stop="handleUndelete(row)" v-else-if="showBtns.removePrjForever && row.status === -2">恢复</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <div style="margin-top: 20px; text-align: right">
      <el-button type="success" :disabled="firstTimeComing || disableAction" :loading="saveLoading" @click="btnSubmit">抽 取</el-button>
      <el-button :disabled="disableAction" @click="onCancel">取 消</el-button>
    </div>

    <SelectProList ref="SelectProList" @selected="onSelectProList" />
  </div>
</template>
<script>
// 项目抽取范围
import auth from '@/plugins/auth'
import { debounce } from '@/utils'
import { CQ_EVAL_RDC_TYPE as RDC_TYPE } from '@/utils/baseData'
import { listBsNode } from '@/api/cqPe/bsNode'
import { listProPoor, getHisRange, savePeRecord, foreverDel, recoverForeverDel, getDept1List } from '@/api/cqPe/peRecord'
import SelectProList from './SelectProList'
import { proRangeStatusList, rdcTypeAuthMap, handleableGenType } from './common'
const searchFields = ['displayName', 'deptName1', 'deptName2', 'deptName3']
import { v4 as uuidv4 } from 'uuid'
import poorProcess from './poorProcess'

export default {
  components: { SelectProList, poorProcess },
  data() {
    return {
      firstTimeComing: false,
      peRecordId: '', // 有值为补抽
      firAss: '', // gc, ds
      proRangeStatusList,
      dept1Loading: false,
      dept1List: [], // 集群
      currDeptId1: '',
      bsNodeLoading: false,
      bsNodeList: [],
      currBsNode: {},
      projectNum: '',
      colNum: undefined, // 初始不展示数字
      bussNum: undefined,
      cityNum: undefined,
      reloadType: 'condition', // 重载方式
      listLoading: false,
      list: [],
      filteredList: [],
      toggleSelect: 'displayName',
      toggleInput: '',
      selected: [],
      saveLoading: false,
      busCacheId: ''
    }
  },
  computed: {
    disableAction() {
      return this.dept1Loading || this.bsNodeLoading || this.listLoading || this.saveLoading
    },
    showBtns() {
      // 操作按钮权限
      const firAss = this.firAss
      const rdcType = rdcTypeAuthMap[this.currBsNode.rdcType] || ''
      const permCode = `cqPe:peRecord:${firAss}:${rdcType}`

      const addPrj = auth.hasPermi(`${permCode}:addPrj`)
      const removePrj = auth.hasPermi(`${permCode}:removePrj`)
      const removePrjForever = auth.hasPermi(`${permCode}:removePrjForever`)

      return { addPrj, removePrj, removePrjForever }
    },
    isSuppDraw() {
      // 是否补抽
      return !!this.peRecordId
    },
    isJq() {
      // 是否集群
      return this.currBsNode.rdcType === RDC_TYPE.DEPT2
    },
    isLastTime() {
      // 是否加载上一次
      return this.reloadType === 'lastTime'
    }
  },
  created() {
    this.btnSubmit = debounce(this.onSubmit, 1e3, true)
  },
  methods: {
    init(opt) {
      this.firstTimeComing = true
      this.peRecordId = opt.peRecordId || ''
      this.firAss = opt.firAss
      this.currDeptId1 = opt.deptId1
      this.currBsNode = opt
      this.getBsNodeList()

      // 先从页面取列表，解决弱网下列表未加载时显示 id
      this.dept1List = opt.dept1List || []
      if (this.isJq) this.getDept1List()

      this.projectNum = 0
      this.colNum = undefined
      this.bussNum = undefined
      this.cityNum = undefined
      this.list = []
      this.filteredList = []
      this.reloadType = 'condition'
      this.getList()
    },
    async getBsNodeList() {
      const { rdcType, belongSystem } = this.currBsNode
      const opt = { pageNum: 1, pageSize: 9999, isEnable: true, rdcType, belongSystem }
      this.bsNodeLoading = true
      const res = await listBsNode(opt).catch(() => false)
      this.bsNodeLoading = false
      if (res === false) return

      let data = res.rows || []
      // 只取 检查,抽查
      data = data.filter(i => handleableGenType.includes(i.generationType))
      this.bsNodeList = data
    },
    changeBsNode(bsNodeId) {
      const deptId1 = this.currDeptId1
      const item = this.bsNodeList.find(i => i.bsNodeId === bsNodeId)
      this.$emit('changeBsNode', { ...item, deptId1 })
    },
    async getDept1List() {
      this.dept1Loading = true
      const res = await getDept1List().catch(() => false)
      this.dept1Loading = false
      if (res === false) return

      const data = res.data || []
      this.dept1List = data
    },
    changeDeptId1() {
      this.getList()
    },
    onReloadType(command) {
      this.reloadType = command || 'condition'
      this.getList()

      // 加载失败，重新获取
      if (!this.bsNodeList.length) this.getBsNodeList()
      if (this.isJq && !this.dept1List.length) this.getDept1List()
    },
    async getList() {
      let error = false
      let sysErrMsg = ''
      this.firstTimeComing = false
      this.busCacheId = uuidv4()
      const { isJq, currDeptId1, isLastTime } = this
      if (isJq && !currDeptId1) return this.$message.warning('暂无集群数据')

      const opt = {
        pageNum: 1,
        pageSize: 9999,
        dimension: 'LAND',
        bsNodeId: this.currBsNode.bsNodeId,
        busCacheId: this.busCacheId,
        needFilter: 1
      }
      if (isJq) opt.deptId1 = currDeptId1

      this.$refs.poorProcessRef.open(this.busCacheId)
      this.listLoading = true
      const reqApi = isLastTime ? getHisRange : listProPoor
      const res = await reqApi(opt).catch(err => {
        if (err instanceof Object && err.message) {
          sysErrMsg = err.message
        } else if (typeof err === 'string') {
          sysErrMsg = err
        }
        return false
      })
      if (!res) {
        error = true
      }
      this.$refs.poorProcessRef.close(error, sysErrMsg)
      this.listLoading = false
      if (res === false) return

      const data = (isLastTime ? res.data : res.rows) || []
      data.map(i => {
        i.removeLoading = false
      })
      data.sort((a, b) => b.status - a.status)
      this.list = data
      this.handleQuery()
    },
    handleQuery() {
      // 本地搜索
      const { toggleSelect, toggleInput, list, selected } = this
      const table = this.$refs.table
      const content = (toggleInput || '').toLowerCase()

      this.listLoading = true
      const data = list.filter(item => {
        // 无搜索
        if (!content) return true

        // 指定字段搜索
        if (toggleSelect) {
          const val = (item[toggleSelect] || '').toLowerCase()
          return val.includes(content)
        }

        // 有一个字段包含搜索值则返回 true
        for (const key of searchFields) {
          const val = (item[key] || '').toLowerCase()
          if (val.includes(content)) return true
        }
        return false
      })

      this.filteredList = data

      this.$nextTick(() => {
        // 保持已选
        const proIdMap = selected.reduce((o, i) => !void (o[i.uniqueId] = 1) && o, {})
        data.map(i => {
          if (i.status < 0 || !proIdMap[i.uniqueId]) return
          table.toggleRowSelection(i, true)
        })
        this.listLoading = false
      })
    },
    sortList() {
      this.$refs.table.clearSelection()
      this.list.sort((a, b) => b.status - a.status)
      this.filteredList.sort((a, b) => b.status - a.status)
    },
    async handleDelete(item) {
      // 状态 1 => -2
      if (item.removeLoading) return
      const res1 = await this.$confirm(`删除后，项目将不再抽取检查。确认删除：${item.displayName}？`, '永久删除', { type: 'warning' }).catch(() => false)
      if (res1 !== 'confirm') return

      const { bsNodeId } = this.currBsNode
      const opt = { ...item, businessType: bsNodeId, status: -2 }
      delete opt.removeLoading

      item.removeLoading = true
      const res = await foreverDel(opt).catch(() => false)
      item.removeLoading = false
      if (res === false) return

      this.msgSuccess('已删除')
      item.status = -2
      this.sortList()
    },
    async handleUndelete(item) {
      // 状态 -2 => 1
      if (item.removeLoading) return
      const res1 = await this.$confirm(`确认恢复：${item.displayName}？`, '警告', { type: 'warning' }).catch(() => false)
      if (res1 !== 'confirm') return

      const { bsNodeId } = this.currBsNode
      const opt = { ...item, businessType: bsNodeId, status: 1 }
      delete opt.removeLoading

      item.removeLoading = true
      const res = await recoverForeverDel(opt).catch(() => false)
      item.removeLoading = false
      if (res === false) return

      this.msgSuccess('已恢复')
      item.status = 1
      this.sortList()
    },
    async statusCancelToNormal(item) {
      // 状态 -1 => 1
      const res1 = await this.$confirm(`确认恢复：${item.displayName}？`, '警告', { type: 'warning' }).catch(() => false)
      if (res1 !== 'confirm') return

      item.status = 1
      this.sortList()
    },
    async removeManuallyAdded(item) {
      // 移除手动添加的
      const res1 = await this.$confirm(`移除后的项目将不在本次抽取范围，确认移除：${item.displayName}？`, '移除范围项目', { type: 'warning' }).catch(() => false)
      if (res1 !== 'confirm') return

      const { list } = this
      const index = list.find(i => i.uniqueId === item.uniqueId)
      list.splice(index, 1)
      this.handleQuery()
    },
    rowClick(row) {
      if (row.status < 0) return
      this.$refs.table.toggleRowSelection(row)
    },
    onSelect(val) {
      this.selected = val
    },
    // 全选
    selectAll() {
      this.$refs.table.toggleAllSelection()
    },
    // 反选
    selectInvert() {
      const { filteredList, selected } = this
      const table = this.$refs.table
      // 全选/全未选，使用已有的切换所有行状态
      if (!selected.length || selected.length === filteredList.length) return table.toggleAllSelection()

      filteredList.filter(i => i.status >= 0).map(row => table.toggleRowSelection(row))
    },
    async removeSelected() {
      // 状态 1 => -1；状态 2 的移掉
      const { selected } = this
      const res1 = await this.$confirm(`移除后的项目将不在本次抽取范围，确认移除选中的 ${selected.length} 项范围项目？`, '移除范围项目', { type: 'warning' }).catch(() => false)
      if (res1 !== 'confirm') return

      const addIds = []
      selected.map(i => {
        if (i.status === 1) return (i.status = -1)
        if (i.status === 2) addIds.push(i.uniqueId)
      })

      // 移除手动添加的
      if (addIds.length) {
        const list = this.list
        this.list = list.filter(i => !addIds.includes(i.uniqueId))
        this.handleQuery()
      }

      this.sortList()
    },
    openSelectProList() {
      this.$refs.SelectProList.open({
        bsNodeId: this.currBsNode.bsNodeId,
        deptId1: this.isJq ? this.currDeptId1 : '',
        list: this.list
      })
    },
    onSelectProList(selected) {
      selected.map(i => (i.status = 2))
      this.list = selected.concat(this.list)
      this.msgInfo(`新增 ${selected.length} 项范围项目`)
      this.handleQuery()
    },
    async onCancel() {
      const res1 = await this.$confirm('确认关闭？', '提示', { type: 'warning' }).catch(() => false)
      if (res1 !== 'confirm') return
      this.$emit('cancel')
    },
    async onSubmit() {
      const { bsNodeId } = this.currBsNode
      const { peRecordId, projectNum, colNum, bussNum, cityNum, list } = this

      if (!bsNodeId) return this.$message.warning('请选择检查类型')
      if (!projectNum) return this.$message.warning('请输入抽取项目数量')
      if (!list.length) return this.$message.warning('项目不能为空')
      if (projectNum > list.length) return this.$message.warning('抽取项目数不能大于项目的数量')

      const frontCondition = {
        colNum: colNum || '',
        bussNum: bussNum || '',
        cityNum: cityNum || ''
      }

      const opt = {
        bsNodeId,
        projectNum,
        needRandom: 1,
        frontCondition: JSON.stringify(frontCondition),
        projectList: list
      }
      if (peRecordId) opt.peRecordId = peRecordId

      this.saveLoading = true
      const res = await savePeRecord(opt).catch(() => false)
      this.saveLoading = false
      if (res === false) return

      // 抽出的数量未满足额定数量
      const proCnt = res.data.rltProIds?.length || 0
      if (proCnt < projectNum) this.$message.warning(`请注意: 应查项目范围中仅剩${proCnt}个待查项目`)

      this.$emit('ok', res.data)
    }
  }
}
</script>
<style lang="scss" scoped>
.ProDrawRange-box {
  position: relative;
  min-width: 850px;
  overflow: hidden;
}
.first-load-btns {
  position: absolute;
  width: 100%;
  height: 100%;
  z-index: 11;
  display: flex;
  justify-content: center;
  align-items: center;
  backdrop-filter: blur(2px);
  .btn {
    display: block;
    width: 100px;
    height: 50px;
    padding: 0;
    &:hover {
      transform: scale(1.1);
      box-shadow: 1px 5px 5px rgba(0, 0, 0, 0.1);
    }
  }
  .btn1 {
    border-radius: 50px 50px 0 0;
    border-bottom: 0;
  }
  .btn2 {
    border-radius: 0 0 50px 50px;
    border-top: 0;
    margin-left: unset;
  }
  .desc {
    color: #5e6d82;
    margin-left: 10px;
    font-size: 12px;
    line-height: 50px;
  }
}
.el-input-group__prepend {
  padding: 0 10px;
}
.table-wrap {
  position: relative;
}
</style>
